package mk.edu.ii.navigatemacedonia;


import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.View.OnTouchListener;
import android.widget.AdapterView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class ResultsView extends Activity {


	public static final String USER_PREFERENCE="my_preferences";
	public static final int SORT_BY_DISTANCE = 0;
	public static final int SORT_BY_RATING = 1;
	ArrayList<Site> sites = new ArrayList<Site>();
	Site [] sites_array;	
	String []sites_list ;
	TextView addressTextView ;
	ImageButton refreshButton;
	Location myLocation = new Location(LocationManager.GPS_PROVIDER);
	Integer radius, category;
	String searchText;
	private Handler handler = new Handler();
	private Context context;
	ProgressDialog myProgressDialog = null;
	
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.resultview);
        
        context = getApplicationContext();
        addressTextView = (TextView)findViewById(R.id.second_Addres);
        refreshButton = (ImageButton)findViewById(R.id.refresh_button);
        
        Intent intent = getIntent();        

        myLocation.setLatitude(intent.getDoubleExtra("latitude",0d));
        myLocation.setLongitude(intent.getDoubleExtra("longitude", 0d));
        radius = intent.getIntExtra("radius", 0);
        category = intent.getIntExtra("category",0);
        searchText = intent.getStringExtra("searchText");
        
        getSitesThread();
      //  getResultsFromService();
        
        addressTextView.setText(ReverseGeoCoding(myLocation.getLatitude(), myLocation.getLongitude()));
        
        
        ListView listView = (ListView)findViewById(R.id.sitesListView);
        
        
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        	public void onItemClick(AdapterView<?> parent, View view, int position, long id){
        		
        		Intent siteInfoView = new Intent(view.getContext(),SiteInfoActivity.class);
        		
        		siteInfoView.putExtra("site", sites.get((int)id));
        		siteInfoView.putExtra("longitude", myLocation.getLongitude());
        		siteInfoView.putExtra("latitude", myLocation.getLatitude());
    			startActivity(siteInfoView);
    			
        	}
        });
        
        
        new OnKeyListener(){

			public boolean onKey(View v, int keyCode, KeyEvent event) {
				
					if(keyCode == KeyEvent.KEYCODE_BACK)
						finish();
				return onKey(v, keyCode, event);
			}
        	
        };
        
        refreshButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				getSitesThread();
			}
		});
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		super.onCreateOptionsMenu(menu);
		
		menu.add(1,1,Menu.NONE,getResources().getStringArray(R.array.sort)[0]);
    	menu.add(1,2,Menu.NONE,getResources().getStringArray(R.array.sort)[1]);
    	return true;
	}
	
	
	
	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		super.onOptionsItemSelected(item);
    	switch (item.getItemId()) {
       	case 1:{
       		//logout();
       		populateLocationList((ListView)findViewById(R.id.sitesListView), SORT_BY_DISTANCE);
       		return true;
       	}
       	case 2:{
       		//update();
       		populateLocationList((ListView)findViewById(R.id.sitesListView), SORT_BY_RATING);
       		return true;
       	}
       	
    	}
    	return true;
	}
	
		
	private void getSitesThread() {
		myProgressDialog = ProgressDialog.show(ResultsView.this,
                "Please wait...", "Try to get information from server...", true);
		Thread thread = new Thread(null, doBackgroundThreadProcessing, "Background");
		thread.start();
		
	}
	
	
	private Runnable doBackgroundThreadProcessing = new Runnable() {
		public void run() {
			getResultsFromService();
			myProgressDialog.dismiss();
		}
	};
	
	private void getResultsFromService() {
		
		ServiceConnect serviceConnect= ServiceConnect.getInstance(getApplicationContext(),handler);
		
		if(myLocation !=null){
			
	        sites = serviceConnect.getSitesFromService(handler
	        		, myLocation.getLongitude()
	        		, myLocation.getLatitude()
	        		, radius
	        		, category.toString()
	        		, "0"
	        		, searchText);
	        
	        if (sites!=null){
	        	handler.post(doUpdateGUI);
	        }
	        else{
	        	handler.post(toast);
	        	
	        }
		}
	}
	
	private Runnable doUpdateGUI = new Runnable() {
		public void run() {
			populateLocationList((ListView)findViewById(R.id.sitesListView),SORT_BY_DISTANCE);
		}
	};
	private Runnable toast = new Runnable() {
		public void run() {
			String msg = "No sites found";
    		int duration = Toast.LENGTH_SHORT;
    		Toast toast = Toast.makeText(context, msg, duration);
    		toast.show();
		}
	};

	public void populateLocationList(ListView locationListView, int sort_by){
		if(sites!=null){	
		for(int i=0;i<sites.size();i++){
    		Location dest = new Location(LocationManager.GPS_PROVIDER);
    		dest.setLatitude(sites.get(i).getSiteLatitude());
    		dest.setLongitude(sites.get(i).getSiteLongitude());
    		Float distance=myLocation.distanceTo(dest);
    		sites.get(i).setSiteDistance(distance);
    		myLocation.bearingTo(dest);
    		sites.get(i).setSiteBearing(myLocation.bearingTo(dest));
    	}
		if(sort_by==0){
			Collections.sort(sites,new DistComp());
		}
		else{
			Collections.sort(sites,new RatingComp());
		}
        SiteAdapter siteAdapter = new SiteAdapter(this, R.layout.siteitem, sites);
        
        //Bind the array adapter to the listview.
        locationListView.setAdapter(siteAdapter);
        
        //seting the choice mode to SingleChoiceMode=1
        locationListView.setChoiceMode(ListView.CHOICE_MODE_NONE);
		}
     }
	
//	private void populateSpinner(Spinner spinner) {
//    	
//    	ArrayAdapter<CharSequence> aAdapter;
//    	aAdapter = ArrayAdapter.createFromResource(this,R.array.sort,android.R.layout.simple_spinner_item);
//    	aAdapter.setDropDownViewResource(
//    			android.R.layout.simple_spinner_dropdown_item);
//    	spinner.setAdapter(aAdapter);
//    	spinner.setSelection(0);
//    	
//    }
	
	private String ReverseGeoCoding(Double latitude,Double longitude)
    {
    	Geocoder gc = new Geocoder(getApplicationContext(), Locale.getDefault());
   	    
    	try {
    		List<Address> addresses = gc.getFromLocation(latitude, longitude, 1);
    		StringBuilder sb = new StringBuilder();
   			if (addresses.size() > 0) {
   				Address address = addresses.get(0);
   				for(int i=0;i<3;i++)
   					if(address.getAddressLine(i)!=null)
   						sb.append(address.getAddressLine(i)+", ");
   					else
   						sb.append("");
   				return sb.toString();
   			} 
   			else {
   				return "No location information found";
   			}
   	    }
        catch (Exception e) {return "No location information found";} 
    }
	
	class DistComp implements Comparator<Object>{

		public int compare(Object object1, Object object2) {
			
			Float site1 = ((Site)object1).getSiteDistanceF();
			Float site2 = ((Site)object2).getSiteDistanceF();
			return site1.compareTo(site2);
		}
		
	}
	
	class RatingComp implements Comparator<Object>{

		public int compare(Object object1, Object object2) {
			
			Float site1 = ((Site)object1).getSiteRating();
			Float site2 = ((Site)object2).getSiteRating();
			return site2.compareTo(site1);
		}
		
	}
}
